/**
 * This file is part of 1genia trampoline
 * Copyright (C) 2007 1genia (contact@1genia.com)
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; version 3 of the License. 
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details. 
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; see the file COPYING.TXT.  If not,
 * write to the Free Software Foundation, Inc., 51 Franklin Street,
 * Fifth Floor, Boston, MA 02110-1301, USA. 
 **/
package com.genia.toolbox.web.gwt.basics.client.widget;

import java.util.Date;

import com.genia.toolbox.web.gwt.basics.client.GwtHelper;
import com.genia.toolbox.web.gwt.basics.client.i18n.I18nArrayCallBack;
import com.genia.toolbox.web.gwt.basics.client.i18n.I18nCallBack;
import com.genia.toolbox.web.gwt.basics.client.message.Messages;
import com.google.code.p.gwtchismes.client.GWTCDatePicker;
import com.google.gwt.user.client.Command;

/**
 * extends {@link GWTCDatePicker} to use RPC to get i18n values.
 */
public class I18nDatePicker
    extends GWTCDatePicker
{

  /**
   * the name of the days of the week.
   */
  private static transient String[] weekMessages = null;

  /**
   * the name of the months.
   */
  private static transient String[] monthMessages = null;

  /**
   * the instance of {@link I18nDatePicker} for the floating one.
   */
  private static I18nDatePicker floatingDatePicker = null;



  /**
   * returns a shared instance of a floating {@link I18nDatePicker}. A shared
   * instance can be used, because only one floating {@link I18nDatePicker} can
   * be visible at all time.
   * 
   * @return a shared instance of a floating {@link I18nDatePicker}
   */
  public static I18nDatePicker getFloatingDatePicker()
  {
    synchronized (I18nDatePicker.class) {
      if (floatingDatePicker == null) {
        floatingDatePicker = new I18nDatePicker(true);
      }
    }
    return floatingDatePicker;
  }



  /**
   * constructor for a embeded {@link I18nDatePicker}.
   */
  public I18nDatePicker()
  {
    this(false);
  }



  /**
   * Constructor, you need specify the behaviour: floating dialog box or embeded
   * widget.
   * 
   * @param dialog
   *          true if you wan an independient and drageable dialog box when the
   *          picker is showed
   */
  private I18nDatePicker(boolean dialog)
  {
    super(dialog);
    setMinimalDate(null);
    setMaximalDate(null);
    setSelectedDate(new Date());
    setHelp(null);
    init(new Command()
    {
      public void execute()
      {
        setLocale(weekMessages, monthMessages, 1);
      }
    });

  }



  /**
   * initialize the i18n messages and then execute the {@link Command} given in
   * arguments.
   * 
   * @param command
   *          the command to execute, once the i18n initialization is done
   */
  private static void init(final Command command)
  {
    if (monthMessages == null) {
      GwtHelper.translateArray(Messages.WEEKDAY_MESSAGES, new I18nArrayCallBack()
      {

        public void getMessages(final String[] weekMessages)
        {
          GwtHelper.translateArray(Messages.MONTH_MESSAGE, new I18nArrayCallBack()
          {

            public void getMessages(final String[] monthMessages)
            {
              I18nDatePicker.weekMessages = weekMessages;
              I18nDatePicker.monthMessages = monthMessages;
              if (command != null) {
                command.execute();
              }
            }
          });
        }
      });
    }
    else {
      if (command != null) {
        command.execute();
      }
    }
  }



  /**
   * Basic method to format dates.
   * 
   * @param dateFormat
   *          (supported dddd ddd dd yyyy yy MMMM MMM MM)
   * @param date
   *          the date to display
   * @param callback
   *          the callback that will use the formated string.
   */
  public static void formatDate(final String dateFormat, final Date date, final I18nCallBack callback)
  {
    if (monthMessages == null) {
      init(new Command()
      {

        public void execute()
        {
          callback.getMessage(formatDate(dateFormat, date, monthMessages, weekMessages));
        }

      });
    }
    else {
      callback.getMessage(formatDate(dateFormat, date, monthMessages, weekMessages));
    }
  }
}
